package com.fingard.dsp.bank.directbank.citic02.util;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;

import com.lsy.baselib.crypto.algorithm.DESede;
import com.lsy.baselib.crypto.algorithm.RSA;
import com.lsy.baselib.crypto.protocol.PKCS7Signature;
import com.lsy.baselib.crypto.util.Base64;
import com.lsy.baselib.crypto.util.CryptUtil;
import com.lsy.baselib.crypto.util.FileUtil;

public class OLPdecrypt {
	public static byte[] LinkByteArrays(byte[] arr1, byte[] arr2) {
		int n1 = arr1.length;
		int n2 = arr2.length;
		byte[] newArr = new byte[n1 + n2];
		System.arraycopy(arr1, 0, newArr, 0, n1);
		System.arraycopy(arr2, 0, newArr, n1, n2);
		return newArr;
	}

	public static int indexOf(byte[] data, byte[] pattern, int fromIndex) {
		int[] failure = computeFailure(pattern);

		int j = 0;
		if (data.length == 0)
			return -1;
		if (data.length - fromIndex <= 0)
			return -1;

		for (int i = fromIndex; i < data.length; i++) {
			while (j > 0 && pattern[j] != data[i]) {
				j = failure[j - 1];
			}
			if (pattern[j] == data[i]) {
				j++;
			}
			if (j == pattern.length) {
				return i - pattern.length + 1;
			}
		}
		return -1;
	}

	private static int[] computeFailure(byte[] pattern) {
		int[] failure = new int[pattern.length];

		int j = 0;
		for (int i = 1; i < pattern.length; i++) {
			while (j > 0 && pattern[j] != pattern[i]) {
				j = failure[j - 1];
			}
			if (pattern[j] == pattern[i]) {
				j++;
			}
			failure[i] = j;
		}

		return failure;
	}

	public static byte[] decrypt_verify(byte[] srcBytes, String ownKeyStorePwd, String ownKeyStorePath,
										String ownCertPath) {

		try {
			byte[] byte_MsgHead1 = new byte[10]; // 10字节报文头，后续信息长度
			// byte[] byte_MsgHead2 = new byte[10]; //
			// 10字节报文头，标识位(P=明文，E=密文)和保留域
			System.arraycopy(srcBytes, 0, byte_MsgHead1, 0, 10);
			// System.arraycopy(byte_接收的报文头和密文报文体, 10, byte_MsgHead2, 0, 10);

			int bodyLen = Integer.valueOf(new String(byte_MsgHead1));
			byte[] encryptPlain = new byte[bodyLen];
			System.arraycopy(srcBytes, 10, encryptPlain, 0, bodyLen);

			byte[] decrptData = null;
			String sKey = null;
			String openTag = "<sessionkey>";
			String closeTag = "</sessionkey>";
			byte[] encryptData = null;

			int start = indexOf(encryptPlain, openTag.getBytes(), 0);
			if (start != -1) {
				int end = indexOf(encryptPlain, closeTag.getBytes(), start + openTag.length());
				if (end != -1) {
					byte[] byte_sKey = new byte[end - start - openTag.length()];
					System.arraycopy(encryptPlain, start + openTag.length(), byte_sKey, 0,
							end - start - openTag.length());
					sKey = new String(byte_sKey);

					encryptData = new byte[encryptPlain.length - end - closeTag.length()];
					System.arraycopy(encryptPlain, end + closeTag.length(), encryptData, 0,
							encryptPlain.length - end - closeTag.length());
				} else {
					return null;
				}
			} else {
				return null;
			}

			char[] recverPrivKeyPass = new String(ownKeyStorePwd).toCharArray();
			byte[] base64EncodedPrivatekey = FileUtil.read4file(ownKeyStorePath);
			PrivateKey recverPrivKey = CryptUtil.decryptPrivateKey(Base64.decode(base64EncodedPrivatekey),
					recverPrivKeyPass); // 接收方私钥
			byte[] sessionEncrypt = RSA.decrypt(Base64.decode(sKey.getBytes()), recverPrivKey.getEncoded());
			byte[] iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
			decrptData = DESede.decrypt(encryptData, sessionEncrypt, iv);

			@SuppressWarnings("unused")
			String b64StrSign = null;
			String openTag2 = "<signature>";
			String closeTag2 = "</signature>";
			byte[] decryptedPlain = null;

			int start2 = indexOf(decrptData, openTag2.getBytes(), 0);
			if (start2 != -1) {
				int end2 = indexOf(decrptData, closeTag2.getBytes(), start2 + openTag2.length());
				if (end2 != -1) {
					byte[] byte_b64sign = new byte[end2 - start2 - openTag2.length()];
					System.arraycopy(decrptData, start2 + openTag2.length(), byte_b64sign, 0,
							end2 - start2 - openTag2.length());
					b64StrSign = new String(byte_b64sign);

					decryptedPlain = new byte[decrptData.length - end2 - closeTag2.length()];
					System.arraycopy(decrptData, end2 + closeTag2.length(), decryptedPlain, 0,
							decrptData.length - end2 - closeTag2.length());
				} else {
					return null;
				}
			} else {
			}
			decryptedPlain = decrptData;

			/*
			 * if (start2 != -1) { byte[] base64EncodedSenderCert =
			 * FileUtil.read4file(ownCertPath); X509Certificate signerCertificate =
			 * CryptUtil.generateX509Certificate(Base64.decode(base64EncodedSenderCert));
			 * PublicKey senderPubKey = signerCertificate.getPublicKey(); boolean
			 * verifyResult =
			 * PKCS7Signature.verifyDetachedSignature(decryptedPlain,Base64.decode(
			 * b64StrSign.getBytes()), senderPubKey); } else {
			 *
			 * }
			 */
			return decryptedPlain;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


	public static byte[] decrypt_verify2(byte[] srcBytes, String ownKeyStorePwd, String ownKeyStorePath, String ownCertPath)
	{
		try
		{


			byte[] byte_MsgHead1 = new byte[10]; // 6字节报文头，后续信息长度
			byte[] byte_MsgHead2 = new byte[10]; // 10字节报文头，标识位(P=明文，E=密文)和保留域
			System.arraycopy(srcBytes, 0, byte_MsgHead1, 0, 10);
			System.arraycopy(srcBytes, 10, byte_MsgHead2, 0, 10);

			int bodyLen = Integer.valueOf(new String(byte_MsgHead1)) - 10;
			byte[] byte_报文密文 = new byte[bodyLen];
			System.arraycopy(srcBytes, 20, byte_报文密文, 0, bodyLen);

			byte[] byte_解密后数据 = null;
			if (byte_MsgHead2[0] != 'E')
			{
				byte_解密后数据 = byte_报文密文; // 明文
			}
			else
			{
				String sMsg = new String(byte_报文密文);
				String sKey = null;
				String openTag = "<sessionkey>";
				String closeTag = "</sessionkey>";
				byte[] byte_密文数据 = null;

				int start = sMsg.indexOf(openTag);
				if (start != -1)
				{
					int end = sMsg.indexOf(closeTag, start + openTag.length());
					if (end != -1)
					{
						sKey = sMsg.substring(start + openTag.length(), end);
						byte_密文数据 = new byte[byte_报文密文.length - end - closeTag.length()];
						System.arraycopy(byte_报文密文, end + closeTag.length(), byte_密文数据, 0, byte_报文密文.length - end - closeTag.length());
					}
					else
					{
						return null;
					}
			} else {
					return null;
				}

				char[] recverPrivKeyPass = new String(ownKeyStorePwd).toCharArray();
				byte[] base64EncodedPrivatekey = FileUtil.read4file(ownKeyStorePath);
				PrivateKey recverPrivKey = CryptUtil.decryptPrivateKey(Base64.decode(base64EncodedPrivatekey), recverPrivKeyPass); // 接收方私钥
				byte[] byte_会话密钥明文 = RSA.decrypt(Base64.decode(sKey.getBytes()), recverPrivKey.getEncoded());
				byte[] iv = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
				byte_解密后数据 = DESede.decrypt(byte_密文数据, byte_会话密钥明文, iv);
			}

			String sData = new String(byte_解密后数据);
			String b64StrSign = null;
			String openTag2 = "<signature>";
			String closeTag2 = "</signature>";
			byte[] byte_解密后报文 = null;

			int start2 = sData.indexOf(openTag2);
			if (start2 != -1)
			{
				int end2 = sData.indexOf(closeTag2, start2 + openTag2.length());
				if (end2 != -1)
				{
					b64StrSign = sData.substring(start2 + openTag2.length(), end2);
					byte_解密后报文 = new byte[byte_解密后数据.length - end2 - closeTag2.length()];
					System.arraycopy(byte_解密后数据, end2 + closeTag2.length(), byte_解密后报文, 0, byte_解密后数据.length - end2 - closeTag2.length());
				}
				else
				{
					return null;
				}
			}
			else
			{
				// return null;
			}

			if (start2 != -1)
			{
				byte[] base64EncodedSenderCert = FileUtil.read4file(ownCertPath);
				X509Certificate signerCertificate = CryptUtil.generateX509Certificate(Base64.decode(base64EncodedSenderCert));

				PublicKey senderPubKey = signerCertificate.getPublicKey();

				boolean 验签结果 = PKCS7Signature.verifyDetachedSignature(byte_解密后报文, Base64.decode(b64StrSign.getBytes()), senderPubKey);
			}
			else
			{
				byte_解密后报文 = byte_解密后数据;
			}

			return byte_解密后报文;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
}
